package com.sdleyou.treepro.common.service.impl;

import com.sdleyou.treepro.common.exception.ServiceException;
import com.sdleyou.treepro.common.model.convert.OrderDO2OrderVOConverter;
import com.sdleyou.treepro.common.model.dao.OrderDO;
import com.sdleyou.treepro.common.model.dao.Page;
import com.sdleyou.treepro.common.model.dao.UserDO;
import com.sdleyou.treepro.common.model.enums.ErrorCodeEnum;
import com.sdleyou.treepro.common.model.vo.OrderVO;
import com.sdleyou.treepro.common.model.vo.TreeVO;
import com.sdleyou.treepro.common.rabbitmq.AmqpExchange;
import com.sdleyou.treepro.common.rabbitmq.message.TreeChangeMsg;
import com.sdleyou.treepro.common.service.MongoPageManager;
import com.sdleyou.treepro.common.service.OrderManager;
import com.sdleyou.treepro.common.service.TreeManager;
import com.sdleyou.treepro.common.service.UserAchievementManager;
import com.sdleyou.treepro.common.utils.DateUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderManagerImpl implements OrderManager {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private TradeSnCreatorImpl tradeSnCreator;
    @Autowired
    private MongoPageManager mongoPageManager;
    @Autowired
    private TreeManager treeManager;
    @Autowired
    private UserAchievementManager userAchievementManager;
    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 订单列表
     */
    @Override
    public Page<OrderVO> getOrderList(String userId, Integer orderStatus, Integer pageNum, Integer pageSize) {
        Query query = new Query();
        query.addCriteria(Criteria.where("user_id").is(userId));
        if(orderStatus!=null) {
            query.addCriteria(Criteria.where("order_status").is(orderStatus));
        }
        query.with(Sort.by(Sort.Order.desc("created_at")));

        Page page = mongoPageManager.pageQuery(query, OrderDO.class, pageSize, pageNum);
        List<OrderDO> data = page.getData();
        List<OrderVO> collect = data.stream().map(OrderDO2OrderVOConverter::convert).collect(Collectors.toList());
        return new Page<>(page.getPageNo(), page.getDataTotal(), page.getPageSize(), collect);
    }

    /**
     * 用户的所有订单列表
     */
    @Override
    public List<OrderVO> getAllOrder(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("user_id").is(userId).and("order_status").is(1).and("pay_status").is(1));
        List<OrderDO> orderDOS = mongoTemplate.find(query, OrderDO.class);
        return orderDOS.stream().map(OrderDO2OrderVOConverter::convert).collect(Collectors.toList());
    }

    /**
     * 添加订单
     */
    @Override
    public OrderVO addOrder(String userId, String treeId, Integer num) {
        OrderDO orderDO = new OrderDO();
        TreeVO treeVO = treeManager.treeInfoById(treeId);
        orderDO.setOrderSn(tradeSnCreator.generateOrderSn());
        orderDO.setUserId(userId);
        orderDO.setOrderStatus(0);
        orderDO.setPayStatus(0);
        orderDO.setPayAt(0L);
        orderDO.setOrderAmount(treeVO.getTreePrice() * num);
        orderDO.setTreeId("");
        orderDO.setTreeType(treeVO.getTreeType());
        orderDO.setTreeNumber(num);
        orderDO.setCreatedAt(DateUtil.getDateline());
        orderDO.setGmtCreate(DateUtil.getDateline());
        orderDO.setGmtModified(DateUtil.getDateline());

        mongoTemplate.insert(orderDO);

        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orderDO, orderVO);
        return orderVO;
    }

    /**
     * 通过订单号修改订单状态
     */
    @Override
    public Map<String, String> updateOrderStatus(String orderSn) {
        Query query = new Query();
        query.addCriteria(Criteria.where("order_sn").is(orderSn));
        OrderDO orderDO = mongoTemplate.findOne(query, OrderDO.class);
        if(orderDO == null){
            throw new ServiceException(ErrorCodeEnum.E600.code(), "该订单不存在");
        }
        Update update = new Update();
        update.set("order_status", 1); //订单状态，已完成
        update.set("pay_status", 1); //支付状态，已支付
        update.set("pay_at", DateUtil.getDateline());
        update.set("gmt_modified", DateUtil.getDateline());
        mongoTemplate.updateFirst(query, update, OrderDO.class);

        //更新用户植树量
        Query queryUser = new Query(Criteria.where("user_id").is(orderDO.getUserId()));
        UserDO userDO = mongoTemplate.findOne(queryUser, UserDO.class);
        Update updateUser = new Update();
        updateUser.set("total_tree", userDO.getTotalTree() + 1);
        mongoTemplate.updateFirst(queryUser, updateUser, UserDO.class);
        //更新总树
        //userAchievementManager.updateTotalTree(orderDO.getTreeNumber().longValue());
        this.amqpTemplate.convertAndSend(AmqpExchange.TOTAL_TREE_CHANGE, AmqpExchange.TOTAL_TREE_CHANGE + "_ROUTING", new TreeChangeMsg(orderDO.getTreeNumber().longValue()));

        return null;
    }
}
